package controller.parameterpanels;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JTextField;

import model.scaling.IEBenchmarkScaling;
import model.scaling.IIndustrialSector;
import view.AlphaTextField;
import view.CenterTabbedPane.EBenchmarkTab;
import view.EBenchmarkPanel;
import view.IObserver;
import view.parameterpanels.LocComIndProdParameterPanel;
import controller.CtrInformationPanel;
import controller.IControllable;

//#Neu
/**
* The class {@code CtrIndustrialSectorPanel} controls the behavior of an 
* industrial sector input parameter panel. 
* @author Sebastian Perlwitz
*
*/
public class CtrIndustrialSectorPanel implements IControllable, IObserver {
	
	/**
	 * The controller of the information panel.
	 */
    private CtrInformationPanel infoPanelController;
    
    /**
     * This controller's view.
     */
    private LocComIndProdParameterPanel paramPanel;
    
    /**
     * The referenced calculation model.
     */
    private IEBenchmarkScaling eBenchmarkScaling;
    
    /**
     * The referenced model.
     */
    private IIndustrialSector industry;
    
    /**
     * To create a new {@code CtrCompanyPanel}.
     * @param eBenchmarkScaling the eBenchmarkScaling model connected to 
     * the controller.
     * @param infoPanelCtr the information panel controller.
     */
	public CtrIndustrialSectorPanel(
			IEBenchmarkScaling eBenchmarkScaling,
            CtrInformationPanel infoPanelController) {
		this.eBenchmarkScaling = eBenchmarkScaling;
        this.infoPanelController = infoPanelController;
        
        // Set industry as the first industrial sector that was created.
        industry = eBenchmarkScaling.getIndustrialSector(1);
        
        createView(null);
        init();
	}
	
	@Override
	public void createView(String logoPath) {
		
		paramPanel = new LocComIndProdParameterPanel(
				infoPanelController, EBenchmarkTab.INDUSTRY_PARAMETERS);
		LocComIndProdParameterPanel industryPanel =
				(LocComIndProdParameterPanel) paramPanel;
		
		// To add listeners to the buttons "+" and "-".
		industryPanel.getAddButton().addActionListener(
				addIndustryListener());
		industryPanel.getRemoveButton().addActionListener(
				removeIndustryListener());
	}
	
	/**
	 * To create a listener for the button that adds a new industrial sector.
	 * @return The button's listener.
	 */
	private ActionListener addIndustryListener() {
		return new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent arg0) {
					addParameterPanel(
							eBenchmarkScaling.addIndustrialSector());
					paramPanel.revalidate();
				}
			};
	}
		
	/**
	 * To create a listener for the button that removes a new industrial sector.
	 * @return The button's listener.
	 */
	private ActionListener removeIndustryListener() {
		return new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				// There must be at least one industrial sector.
				if(eBenchmarkScaling.getIndustrialSectors().size() > 1) {
					removeParameterPanel();
					eBenchmarkScaling.removeIndustrialSector();
					paramPanel.revalidate();	
				}								
			}			
		};
	}
	
	/**
	 * To initiate the view of this controller.
	 */
	private void init() {
		addParameterPanel(industry);
    }
	
	/**
     * To change the text of a parameter panel's border. 
     * @param textField the AlphaTextField.
     * @param newText the text to be set for the border.
     */
	public void changeBorderText(AlphaTextField textField, String newText) {
		
		// Change the corresponding border text when the user renamed the 
		// industrial sector.
		LocComIndProdParameterPanel industryPanel =
				(LocComIndProdParameterPanel) paramPanel;
		int panelIndex = 
				industryPanel.getNameTextFields().indexOf(textField);
		paramPanel.setBorderText(panelIndex, newText);
	}
	
	/**
     * To add a parameter panel to the view.
     * @param industry the industrial sector whose parameter panels gets drawn
     */
	private void addParameterPanel(IIndustrialSector industry) {
		
		// Add the industrial sector Panel.
		LocComIndProdParameterPanel industryPanel = 
				(LocComIndProdParameterPanel) paramPanel;
		addTextFieldListeners(
				industryPanel.addParameterSet(
						industry.getName(),
						industry.getID()));
	}
	
	/**
     * To add a document listener to every text field of a parameter panel.
     * The view of this controller gets registered as an observer in the model.
     * @param textFields the text fields.
     */
	private void addTextFieldListeners(List<JTextField> textFields) {
		
		// When new text fields are added get the new industry.
		industry = eBenchmarkScaling.getIndustrialSector(
				eBenchmarkScaling.getIndustrialSectors().size());
		
		// Register this controller and the paramPanel as an observer in 
		// industry.
		industry.registerObserver(this);
		industry.registerObserver(paramPanel);
		
		// To add text field listeners to the text fields that rename an 
		// industrial sector.
		List<AlphaTextField> alphaTextFields = 
				new ArrayList<AlphaTextField>();
		
		for(JTextField textField : textFields) {
			alphaTextFields.add((AlphaTextField) textField);
		}
		
		// Add the listeners to the text fields that rename an industrial sector.
		for(AlphaTextField textField : alphaTextFields) {
			textField.addDocumentListener(new ListenerAlphaTextField(
					textField,
					this,
					industry,
					eBenchmarkScaling));
		}
	}
	
	/**
     * To remove the last parameter panel from the view.
     */
    public void removeParameterPanel() {
    	paramPanel.removeParameterPanel();
    }
	
	/**
     * To tell the controller that another invalid input was written into
     * one of the text fields.
     */
    public void addInvalidInput() {
    	infoPanelController.getView().showInvalidInputError();
    	paramPanel.setErrorStatus(true);
    	industry.notifyObservers();
    	eBenchmarkScaling.notifyObservers();
    }
    
    /**
     * To tell the controller that another invalid input was corrected.
     */
    public void removeInvalidInput() {
    	infoPanelController.getView().showIndustryStandardMessage();
        paramPanel.setErrorStatus(false);
        industry.notifyObservers();
        eBenchmarkScaling.notifyObservers();
    }
    
    @Override
    public EBenchmarkPanel getView() {
        return paramPanel;
    }

	@Override
	public void update() {
		// Nothing to do here.
	}

}
